home *** CD-ROM | disk | FTP | other *** search
- # Copyright (c) 2003-2006 CORE Security Technologies
- #
- # This software is provided under under a slightly modified version
- # of the Apache Software License. See the accompanying LICENSE file
- # for more information.
- #
- # $Id: printer.py,v 1.2 2006/05/23 21:19:26 gera Exp $
- #
-
- from impacket.structure import Structure
-
- def zeroize(s):
- return '\x00'.join(str(s)) + '\x00'
-
- class SpoolSS_DevModeContainer(Structure):
- alignment = 4
- structure = (
- ('cbBuf','<L-DevMode'),
- ('pDevMode','<L&DevMode'),
- ('DevMode',':'),
- )
-
- class SpoolSS_OpenPrinter(Structure):
- alignment = 4
- opnum = 1
- structure = (
- ('pPrinterName','<L&PrinterName'),
- ('PrinterName','w'),
- # ('pDataType','<L&DataType'),
- ('pDevMode','<L&DevMode'),
- ('DevMode',':',SpoolSS_DevModeContainer),
- ('AccessRequired','<L'),
- ('DataType','w'),
- )
-
- class SpoolSS_PrinterInfo1(Structure):
- alignment = 4
- structure = (
- ('level','<L=1'),
- ('_level','<L=1'),
- ('pPrinterInfo1','<L=0x08081200'),
- ('flags','<L'),
- ('pDescription','<L&Description'),
- ('pName','<L&Name'),
- ('pComment','<L&Comment'),
- ('Description','w'),
- ('Name','w'),
- ('Comment','w'),
- )
-
- class SpoolSS_PrinterInfo2(Structure):
- alignment = 4
- structure = (
- ('level','<L=2'),
- ('_level','<L=2'),
- ('pPrinterInfo2','<L=0x08081200'),
- ('pServerName', '<L&ServerName'),
- ('pPrinterName', '<L&PrinterName'),
- ('pShareName', '<L&ShareName'),
- ('pPortName', '<L&PortName'),
- ('pDriverName', '<L&DriverName'),
- ('pComment', '<L&Comment'),
- ('pLocation', '<L&Location'),
- ('pDevMode', '<L&DevMode'),
- ('pSepFile', '<L&SepFile'),
- ('pPrintProcessor', '<L&PrintProcessor'),
- ('pDatatype', '<L&Datatype'),
- ('pParameters', '<L&Parameters'),
- ('pSecurityDescriptor', '<L&SecurityDescriptor'),
- ('Attributes', '<L=0'),
- ('Priority', '<L=0'),
- ('DefaultPriority', '<L=0'),
- ('StartTime', '<L=0'),
- ('UntilTime', '<L=0'),
- ('Status', '<L=0'),
- ('cjobs', '<L=0'),
- ('AveragePPM', '<L=0'),
- ('ServerName', 'w'),
- ('PrinterName', 'w'),
- ('ShareName', 'w'),
- ('PortName', 'w'),
- ('DriverName', 'w'),
- ('Comment', 'w'),
- ('Location', 'w'),
- ('DevMode', ':'),
- ('SepFile', 'w'),
- ('PrintProcessor', 'w'),
- ('Datatype', 'w'),
- ('Parameters', 'w'),
- ('SecurityDescriptor', ':'),
- )
-
- class SpoolSS_AddPrinter(Structure):
- # opnum from http://bob.marlboro.edu/~msie/2003/it1/tools/ethereal/ethereal-0.9.7/packet-dcerpc-spoolss.h
- opnum = 5
- alignment = 4
- structure = (
- ('pName','<L&Name'),
- ('Name','w'),
- ('info',':',SpoolSS_PrinterInfo2),
- ('blob',':'),
- )
-
- class SpoolSS_DeletePrinter(Structure):
- opnum = 6
- alignment = 4
- structure = (
- ('handle','<L'),
- )
-
- class SpoolSS_AddPrinterEx(Structure):
- opnum = 0x46
- alignment = 4
- structure = (
- ('pName','<L=0x12345678'),
- ('Name','w'),
- ('info',':',SpoolSS_PrinterInfo2),
- ('blob',':'),
- )
-
- class SpoolSS_EnumPrinters(Structure):
- opnum = 0
- alignment = 4
- structure = (
- ('flags','<L'),
- ('pName','<L&Name'),
- ('Name','w'),
- ('level','<L'),
- ('pPrinterEnum','<L&PrinterEnum'),
- ('_cbBuf','<L-PrinterEnum'),
- ('PrinterEnum',':'),
- ('cbBuf','<L-PrinterEnum'),
- )
-
- class SpoolSS_EnumPrinters_answer(Structure):
- alignment = 4
- structure = (
- ('pPrinterEnum','<L&PrinterEnum'),
- ('cbPrinterEnum','<L-PrinterEnum'),
- ('PrinterEnum',':'),
- ('cbNeeded','<L'),
- ('cReturned','<L'),
- )
-
- class SpoolSS_EnumPorts(Structure):
- # fields order (in the wire) from:
- # http://samba.vernstok.nl/docs/htmldocs/manpages-4/pidl.1.html
- opnum = 0x23
- alignment = 4
- structure = (
- ('pName','<L&Name'),
- ('Name','w'),
- ('level','<L'),
- ('pPort','<L&Port'),
- ('_cbBuf','<L-Port'),
- ('Port',':'),
- ('cbBuf','<L-Port'),
- )
-
- class SpoolSS_EnumPorts_answer(Structure):
- alignment = 4
- structure = (
- ('pPort','<L&Port'),
- ('cbPort','<L-Port'),
- ('Port',':'),
- ('cbNeeded','<L'),
- ('cReturned','<L'),
- )
-
- class SpoolSS_AddPort(Structure):
- opnum = 37
- alignment = 4
- structure = (
- ('pName','<L&Name'),
- ('Name','w'),
- ('hWnd','<L'),
- ('pMonitorName','<L&MonitorName'),
- ('MonitorName','w'),
- )
-
- class SpoolSS_PortInfo1(Structure):
- alignment = 4
- structure = (
- ('level','<L=1'),
- ('_level','<L=1'),
- ('pPortInfo1','<L=0x08081200'),
- ('pName','<L&Name'),
- ('Name','w'),
- )
-
- class SpoolSS_AddPortEx(Structure):
- opnum = 61
- alignment = 4
- structure = (
- ('pName','<L&Name'),
- ('Name','w'),
- ('Port',':',SpoolSS_PortInfo1),
- ('cbMonitorData','<L-MonitorData'),
- ('MonitorData',':'),
- # ('pMonitorName','<L&MonitorName'),
- ('MonitorName','w'),
- )
-
- class SpoolSS_AddPrintProcessor(Structure):
- opnum = 14
- alignment = 4
- structure = (
- ('pName','<L&Name'),
- ('Name','w'),
- ('pEnvironment','<L&Environment'),
- ('pPathName','<L&PathName'),
- ('pPrintProcessorName','<L&PrintProcessorName'),
- ('Environment','w'),
- ('PathName','w'),
- ('PrintProcessorName','w'),
- )
-
- class SpoolSS_EnumMonitors(Structure):
- # fields order (in the wire) from:
- # http://samba.vernstok.nl/docs/htmldocs/manpages-4/pidl.1.html
- opnum = 0x24
- alignment = 4
- structure = (
- ('pName','<L&Name'),
- ('Name','w'),
- ('level','<L'),
- ('pMonitor','<L&Monitor'),
- ('_cbBuf','<L-Monitor'),
- ('Monitor',':'),
- ('cbBuf','<L-Monitor'),
- )
-
- class SpoolSS_AddMonitor(Structure):
- # fields order (in the wire) from:
- # http://samba.vernstok.nl/docs/htmldocs/manpages-4/pidl.1.html
- opnum = 0x2e
- alignment = 4
- structure = (
- ('pHostName','<L&HostName'),
- ('HostName','w'),
- ('level','<L'),
- ('level','<L'),
- ('pLevel','<L&level'),
- ('pName','<L&Name'),
- ('pEnvironment','<L&Environment'),
- ('pDLLName','<L&DLLName'),
- ('Name','w'),
- ('Environment','w'),
- ('DLLName','w'),
- )
-
- class SpoolSS_EnumMonitors_answer(Structure):
- alignment = 4
- structure = (
- ('pMonitor','<L&Monitor'),
- ('cbMonitor','<L-Monitor'),
- ('Monitor',':'),
- ('cbNeeded','<L'),
- ('cReturned','<L'),
- )
-
- PRINTER_ENUM_DEFAULT = 0x00000001
- PRINTER_ENUM_LOCAL = 0x00000002
- PRINTER_ENUM_CONNECTIONS = 0x00000004
- PRINTER_ENUM_FAVORITE = 0x00000004
- PRINTER_ENUM_NAME = 0x00000008
- PRINTER_ENUM_REMOTE = 0x00000010
- PRINTER_ENUM_SHARED = 0x00000020
- PRINTER_ENUM_NETWORK = 0x00000040
-
- class PrintSpooler:
- def __init__(self, dce):
- self.dce = dce
-
- def doRequest(self, request, noAnswer = 0, checkReturn = 1):
- self.dce.call(request.opnum, request)
- if noAnswer:
- return
- else:
- answer = self.dce.recv()
- if checkReturn and answer[-4:] != '\x00\x00\x00\x00':
- raise Exception, 'DCE-RPC call returned an error.'
- return answer
-
- def enumPrinters(self, name, flags = 0, level = 1):
- # first get the number of bytes needed
- enumPrinters = SpoolSS_EnumPrinters()
- enumPrinters['level'] = level
- enumPrinters['flags'] = flags
- enumPrinters['Name'] = name
- enumPrinters['PrinterEnum'] = ''
- ans = SpoolSS_EnumPrinters_answer(self.doRequest(enumPrinters, checkReturn = 0))
-
- self.logDebug("enumPrinters() needing %d bytes" % ans['cbNeeded'])
- if ans['cbNeeded'] > 4096:
- raise Exception, "Buffer is too big."
-
- # do the real request
- enumPrinters = SpoolSS_EnumPrinters()
- enumPrinters['level'] = level
- enumPrinters['flags'] = flags
- enumPrinters['Name'] = name
- enumPrinters['PrinterEnum'] = '\x00' * ans['cbNeeded']
-
- ans = SpoolSS_EnumPrinters_answer(self.doRequest(enumPrinters, checkReturn = 0))
- # ans.dump('answer')
-
- def openPrinter(self, printerName, dataType, devMode, accessRequired):
- openPrinter = SpoolSS_OpenPrinter()
- if printerName: openPrinter['PrinterName'] = zeroize(printerName+'\x00')
- if dataType: openPrinter['DataType'] = zeroize(dataType+'\x00')
- if devMode:
- devModeC = SpoolSS_DevModeContainer()
- # devModeC['DevMode'] = devModeC
- devModeC['cbBuf'] = 0
- devModeC['pDevMode'] = 0
- devModeC['DevMode'] = ''
- openPrinter['DevMode'] = '\x00\x00\x00\x00'
- openPrinter['pDevMode'] = 0
- openPrinter['AccessRequired'] = accessRequired
-
- return self.doRequest(openPrinter, checkReturn = 0)
-
- def enumPorts(self, level = 1, noAnswer = 0):
- # this one calls ntdll_RtlAcquirePebLock and ntdll_RtlReleasePebLock
-
- # first get the number of bytes needed
- enumPorts = SpoolSS_EnumPorts()
- enumPorts['level'] = level
- enumPorts['Port'] = ''
- if noAnswer:
- self.doRequest(enumPorts, noAnswer = 1)
- else:
- ans = SpoolSS_EnumPorts_answer(self.doRequest(enumPorts, checkReturn = 0))
-
- # do the real request
- enumPorts = SpoolSS_EnumPorts()
- # enumPorts['Name'] = '\\\x00\\\x00hola\x00\x00'
- enumPorts['level'] = level
- enumPorts['Port'] = '\x00'*ans['cbNeeded']
- ans = SpoolSS_EnumPorts_answer(self.doRequest(enumPorts, checkReturn = 0))
- # ans.dump('answer')
-
- def enumMonitors(self, level = 1):
- # first get the number of bytes needed
- enumMonitors = SpoolSS_EnumMonitors()
- enumMonitors['level'] = level
- enumMonitors['Monitor'] = ''
- ans = SpoolSS_EnumMonitors_answer(self.doRequest(enumMonitors, checkReturn = 0))
-
- # do the real request
- enumMonitors = SpoolSS_EnumMonitors()
- # enumMonitors['Name'] = '\\\x00\\\x00hola\x00\x00'
- enumMonitors['level'] = level
- enumMonitors['Monitor'] = '\x00'*ans['cbNeeded']
- ans = SpoolSS_EnumMonitors_answer(self.doRequest(enumMonitors, checkReturn = 0))
- # ans.dump('answer')
-
- def addMonitor(self, name, monitorName, environment, dllName):
- addMonitor = SpoolSS_AddMonitor()
- addMonitor['level'] = 2
- addMonitor['HostName'] = zeroize(name)
- addMonitor['Name'] = zeroize(monitorName)
- addMonitor['Environment'] = zeroize(environment)
- addMonitor['DLLName'] = zeroize(dllName)
- ans = self.doRequest(addMonitor, checkReturn = 0)
- print "%r" % ans
-
- def addPort(self):
- addPort = SpoolSS_AddPort()
- addPort['Name'] = zeroize('\\192.168.22.90\x00')
- addPort['hWnd'] = 0
- addPort['MonitorName'] = zeroize('LanMan Print Services Port\x00')
-
- return self.doRequest(addPort)
-
- def addPortEx(self):
- port = SpoolSS_PortInfo1()
- port['Name'] = zeroize('Port Name\x00')
-
- addPortEx = SpoolSS_AddPortEx()
- addPortEx['Name'] = zeroize('\\\\192.168.22.90\x00')
- addPortEx['Port'] = port
- addPortEx['cbMonitorData'] = 0
- addPortEx['MonitorData'] = '\x00'*4
- addPortEx['MonitorName'] = zeroize('Monitor Name\x00')
-
- return self.doRequest(addPortEx)
-
- def addPrintProcessor(self):
- addPrintProcessor = SpoolSS_AddPrintProcessor()
- # addPrintProcessor['Name'] = zeroize('\\\\192.168.22.90\x00')
- addPrintProcessor['Environment'] = zeroize('Windows NT x86\x00')
- addPrintProcessor['PathName'] = zeroize('C:\\hola\\manola\x00')
- addPrintProcessor['PrintProcessorName'] = zeroize('chaucha\x00')
-
- return self.doRequest(addPrintProcessor)
-
- def deletePrinter(self, handle):
- deletePrinter = SpoolSS_DeletePrinter()
- deletePrinter['handle'] = handle
- self.doRequest(deletePrinter)
-
- def addPrinter(self, serverName, name, level = 1, flags = 0, comment = None, description = None):
- addPrinter = SpoolSS_AddPrinter()
- # length(Name)+length(PrinterName)+2+2 must be the size of the chunk following the overflown
-
- if serverName is not None:
- addPrinter['Name'] = serverName
-
- if level == 1:
- addPrinter['info'] = SpoolSS_PrinterInfo1()
- addPrinter['info']['Name'] = name
- addPrinter['info']['Description'] = description
- addPrinter['info']['flags'] = flags
- elif level == 2:
- addPrinter['info'] = SpoolSS_PrinterInfo2()
- addPrinter['info']['PrinterName'] = name
- else:
- raise Exception, "Unknown PRINTER_INFO level"
-
- addPrinter['info']['Comment'] = comment
-
- addPrinter['blob'] = ( # to be improved
- "\x00\x00\x00\x00"*4
- )
-
- # addPrinter.dump('addPrinter')
- # addPrinter['info'].dump('info')
- return self.doRequest(addPrinter, checkReturn = 0)
-
- def addPrinterEx(self, serverName, name, comment = None):
- addPrinterEx = SpoolSS_AddPrinterEx()
-
- # length(Name)+length(PrinterName)+2+2 must be the size of the chunk following the overflow in mem
-
- addPrinterEx['Name'] = serverName
-
- addPrinterEx['info'] = SpoolSS_PrinterInfo2()
- addPrinterEx['info']['PrinterName'] = name
- addPrinterEx['info']['Comment'] = comment
-
- addPrinterEx['blob'] = ( # to be improved
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x01\x00\x00\x00\x01\x00\x00\x00"
-
- "\xf8\xf3\x30\x00"
- "\x1c\x00\x00\x00"
- "\xf0\x62\xc9\x00"
- "\xe0\xf1\x30\x00"
- "\x93\x08\x00\x00"
- "\x03\x00\x00\x00"
- "\x00\x00\x00\x00"
- "\x00\x00\x00\x00"
-
- "\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00"
-
- # \\ERATO
- "\x5c\x00\x5c\x00\x45\x00\x52\x00\x41\x00\x54\x00\x4f\x00\x00\x00"
-
- "\x0e\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00"
-
- # Administrator
- "\x41\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00"
- "\x72\x00\x61\x00\x74\x00\x6f\x00\x72\x00\x00\x00"
- )
-
- return self.doRequest(addPrinterEx)
-
-
-
-